R für Linguistik und Sozialwissenschaften (Angewandte Datenverarbeitung und Visualisierung)
  • D. Palleschi
  1. Datenimport
  • Einführung in R und RStudio
  • Datenvisualiserung 1
  • Einführung in Quarto
  • Datentransformation
  • Datenvisualiserung 2
  • Datenimport
  • Deskriptive Statistik
  • Datenvisualisierung 3
  • Data Wrangling 2
  • base R
  • Datenvisualisierung 4
  • Troubleshooting

heutige Themen

  • 1 Einrichtung
    • 1.1 Pakete mit pacman
  • 2 CSV: Comma separated value
    • 2.1 ‘Tidy’ Daten
    • 2.2 Tabelle zu csv
    • 2.3 CSV speichern
  • 3 Das Paket readr
  • 4 Das Paket here
  • 5 Arbeiten mit Daten
    • 5.1 Fehlende Werte
    • 5.2 Spaltennamen
    • 5.3 Pipes
    • 5.4 Variablentypen
  • 6 Andere Dateitypen und Begrenzungszeichen
  • Hausaufgaben
  • Session Info

Andere Formate

  • RevealJS
  • PDF

Datenimport

  • Gesamten Code zeigen
  • Gesamten Code verbergen

  • Quellcode anzeigen

Einlesen lokaler Datendateien

Autor:in
Zugehörigkeit

Daniela Palleschi

Humboldt-Universität zu Berlin

Veröffentlichungsdatum

Di. den 04.06.2024

Geändert

Do. den 20.06.2024

Lernziele

Heute werden wir lernen, wie man:

  • lokale Datendateien (.csv) erstellen und speichern
  • lokale Datendateien mit dem Paket readr importieren
  • mit fehlenden Werten umzugehen
  • Variablen in Faktoren umwandeln

Lesungen

  • Kurs-Website: Kap. 5 - Datenvisualisierung 2
  • Kap. 8 (Datenimport) in Wickham et al. (2023)
  • Kap. 4 (Datenimport) in Nordmann & DeBruine (2022)

Wiederholung

Bis jetzt haben wir gelernt, wie man…

  • Quarto-Skripte für die reproduzierbare Datenanalyse zu verwenden
  • eingebaute Datensätze zu laden
  • Daten mit dplyr-Verben zu verarbeiten
  • Verteilungen und Beziehungen zwischen verschiedenen Variablentypen zu visualisieren

1 Einrichtung

1.1 Pakete mit pacman

  • wir fangen an, das Paket pacman anstelle von install.packages() und library zu benutzen
    • die Funktion p_load() nimmt Paketnamen als Argumente
    • prüft dann, ob Sie das Paket installiert haben
      • wenn ja –> lädt das Paket (genau wie library())
      • wenn nicht –> wird das Paket installiert und dann geladen (wie mit install.packages() + library())
  • dies erspart uns die individuelle Installation neuer Pakete

# install new packages IN THE CONSOLE!
install.packages("pacman")
# load packages (in your script)
pacman::p_load(
               tidyverse, # wrangling
               janitor, # tidying
               here # relative file paths
               )
  • wir haben jetzt tidyverse geladen und die neuen Pakete janitor und here installiert und geladen
    • Um mehr über diese Pakete herauszufinden, geben Sie ?janitor und ?here in der Konsole ein.
  • fügen Sie Ihrem Projektverzeichnis einen Ordner mit dem Namen daten hinzu (der genau gleich geschrieben ist).
RProjects
  • Stellen Sie sicher, dass Sie in der Klasse RProject arbeiten!
  • Falls nicht, folgen Sie der Übung auf der Kurs-Website hier

2 CSV: Comma separated value

  • Es gibt viele verschiedene Dateitypen, die Daten annehmen können, z. B. .xlsx, .txt, .csv, .tsv

  • .csv ist der typischste Dateityp und steht für: Comma Separated Values

  • So sieht eine einfache CSV-Datei aus, wenn man sie als Rohtext betrachtet

Student ID,Full Name,favourite.food,mealPlan,AGE
1,Sunil Huffmann,Strawberry yoghurt,Lunch only,4
2,Barclay Lynn,French fries,Lunch only,5
3,Jayendra Lyne,N/A,Breakfast and lunch,7
4,Leon Rossini,Anchovies,Lunch only,
5,Chidiegwu Dunkel,Pizza,Breakfast and lunch,five
6,Güvenç Attila,Ice cream,Lunch only,6
  • die erste Zeile (die “Kopfzeile”) enthält die Spaltennamen
  • die folgenden Zeilen enthalten die Daten
  • Wie viele Variablen gibt es? Wie viele Beobachtungen?

2.1 ‘Tidy’ Daten

  • Sie wollen, dass Ihre Daten aufgeräumt sind
    • aufgeräumte Daten sind rechteckig, und:
    • jede Spalte steht für eine Variable
    • jede Zeile eine Beobachtung
    • jede Zelle ein Datenpunkt (Abbildung 1)
Abbildung 1: Source: Wickham et al. (2023) (all rights reserved)

2.2 Tabelle zu csv

  • Lassen Sie uns einige Spielzeugdaten in einer Tabellenkalkulation sammeln, die wir dann als CSV-Datei speichern und in R laden werden
    • Klicken Sie hier, um zu einem bearbeitbaren Arbeitsblatt zu gelangen.
    • Geben Sie die relevanten Informationen über sich selbst ein, oder erfinden Sie einige Daten: den Namen eines Haustiers, das Sie haben/hatten, Größe, Geburtsmonat und -tag sowie Ihre erste Sprache. Wenn Sie kein Haustier haben, lassen Sie die Zelle leer.
Abbildung 2: Klicken Sie hier zum Hinzufügen und Herunterladen der Tabelle

2.3 CSV speichern

  • Speichern Sie die Tabelle als groesse_geburtstag.csv auf Ihrem Computer, direkt in einem Ordner namens daten in unserem Projektverzeichnis
Aufgabe 1: Saving a CSV

Beispiel 1  

  1. Erstellen Sie einen neuen Ordner mit dem Namen daten in Ihrem Projektordner (falls Sie das nicht schon getan haben).
  2. Laden Sie das Google Sheet herunter und speichern Sie es in Ihrem daten Ordner als groesse_geburtstag.csv.
  3. Gehen Sie zu Ihrem daten-Ordner und überprüfen Sie, ob die CSV-Datei dort ist.

3 Das Paket readr

  • müssen wir nun die Daten einlesen

  • wir müssen eine Funktion verwenden, die CSV-Daten liest, und angeben, wo sich die Daten in unserem RProject-Ordner befinden

  • Das readr-Paket (Teil von tidyverse) kann die meisten Datentypen einlesen und hat mehrere Funktionen für verschiedene Datentypen


read_csv(here::here("daten", "groesse_geburtstag.csv"))
Tabelle 1: Data from the groesse_geburtstag.csv file as a table.
Größe Geburtsmonat L1 Haustier Was für ein Haustier?
171 5 Englisch Lola Hundin
168 11 Deutsch keine keine
182 4 Deutsch N/A NA
190 8 Deutsch Knut Kater
170 10 Deutsch Emma Hundin
163 2 Deutsch Üzgür Kater
164 7 Italienisch Fipsy Katze
167 12 Schwedisch Anna Fisch
189 10 Norwegisch Arvid Papagei
163 7 Russisch Narzis Kater
159 11 Punjabi Mimi Katze
173 9 Deutsch Percy Hund
Aufgabe 2: readr

Beispiel 2  

  1. Importieren Sie den Datensatz “groesse_geburtstag.csv” und speichern Sie ihn als Objekt mit dem Namen df_groesse.
    • df_ ist die Abkürzung für DataFrame; es ist eine gute Idee, ein Präfix vor Objektnamen zu verwenden, damit wir wissen, was jedes Objekt enthält
  2. Beim Importieren von Daten mit read_csv werden einige Informationen in der Konsole ausgegeben. Was wird gedruckt?
  3. Untersuche den Datensatz mit Funktionen wie summary() oder head()
  4. Sehen Sie etwas Ungewöhnliches?

4 Das Paket here

  • Woher weiß R genau, wo der Ordner daten zu finden ist?
  • unser Arbeitsverzeichnis ist auf den Ort unseres RProjekts auf unserem Computer festgelegt
    • wann immer wir auf Daten in unserem RProjekt zugreifen wollen, sollten wir unseren Dateipfad in here() verschachteln
  • um zu sehen, von wo aus here() startet, führen Sie here() aus
here()
[1] "/Users/danielapalleschi/Documents/IdSL/Teaching/SoSe24/B.A./r4ling_sose2024"
  • Die Ausgabe wird auf allen Rechnern unterschiedlich aussehen, da sie relativ zu dem Ort ist, an dem wir unseren Projektordner abgelegt haben

Image source: Allison Horst (all rights reserved)

5 Arbeiten mit Daten

5.1 Fehlende Werte

  • Sie haben vielleicht einige NA oder N/A Werte bemerkt
    • N/A wurde als Text in einer unserer Beobachtungen geschrieben, und so liest R es als solches
    • NA in R bezieht sich auf fehlende Daten (“Nicht verfügbar”)
    • Echte fehlende Werte sind komplett leer, so dass N/A in unseren df_groesse-Daten nicht wirklich als fehlender Wert gelesen wird.
    • Um dies zu beheben, können wir das Argument na = für die Funktion read_csv() verwenden, das der Funktion read_csv() mitteilt, welche Werte sie mit fehlenden Werten gleichsetzen soll
# force "N/A" to missing values
df_groesse <- read_csv(here::here("daten", "groesse_geburtstag.csv"),
                        na = "N/A")
# print the head of the data set
head(df_groesse)
# A tibble: 6 × 5
  Größe Geburtsmonat L1       Haustier `Was für ein Haustier?`
  <dbl>        <dbl> <chr>    <chr>    <chr>                  
1   171            5 Englisch Lola     "Hundin"               
2   168           11 Deutsch  keine    "keine"                
3   182            4 Deutsch  <NA>     ""                     
4   190            8 Deutsch  Knut     "Kater"                
5   170           10 Deutsch  Emma     "Hundin"               
6   163            2 Deutsch  Üzgür    "Kater"                
  • der Wert, der vorher "" war, wird als NA gelesen
  • aber was ist mit der leeren Zelle? Wir haben jetzt überschrieben, dass read_csv() leere Zellen als NA liest
    • Nun wollen wir read_csv() anweisen, mehr als eine Art von Eingabe als NA zu lesen, d.h. wir wollen es anweisen, "" und "N/A" als NA zu lesen
    • Dazu verwenden wir unsere immer nützliche Verkettungsfunktion: c()
    • lassen Sie uns auch ‘keine’ als NA’s einschließen
# force "N/A", empty cells, and 'keine' to missing values
df_groesse <- read_csv(here::here("daten", "groesse_geburtstag.csv"),
                        na = c("N/A","", "keine"))
# print the head of the data set
head(df_groesse)
# A tibble: 6 × 5
  Größe Geburtsmonat L1       Haustier `Was für ein Haustier?`
  <dbl>        <dbl> <chr>    <chr>    <chr>                  
1   171            5 Englisch Lola     Hundin                 
2   168           11 Deutsch  <NA>     <NA>                   
3   182            4 Deutsch  <NA>     <NA>                   
4   190            8 Deutsch  Knut     Kater                  
5   170           10 Deutsch  Emma     Hundin                 
6   163            2 Deutsch  Üzgür    Kater                  

5.2 Spaltennamen

  • Ein Spaltenname in unseren Daten ist von Backticks umgeben (z.B. `Was für ein Haustier?`)
    • Das liegt daran, dass er ein Leerzeichen enthält, das syntaktisch nicht gültig ist.
    • Eine schnelle Lösung ist die Funktion clean_names() aus dem Paket janitor, das wir bereits geladen haben
clean_names(df_groesse)
# A tibble: 12 × 5
   grosse geburtsmonat l1          haustier was_fur_ein_haustier
    <dbl>        <dbl> <chr>       <chr>    <chr>               
 1    171            5 Englisch    Lola     Hundin              
 2    168           11 Deutsch     <NA>     <NA>                
 3    182            4 Deutsch     <NA>     <NA>                
 4    190            8 Deutsch     Knut     Kater               
 5    170           10 Deutsch     Emma     Hundin              
 6    163            2 Deutsch     Üzgür    Kater               
 7    164            7 Italienisch Fipsy    Katze               
 8    167           12 Schwedisch  Anna     Fisch               
 9    189           10 Norwegisch  Arvid    Papagei             
10    163            7 Russisch    Narzis   Kater               
11    159           11 Punjabi     Mimi     Katze               
12    173            9 Deutsch     Percy    Hund                
  • Das sieht besser aus! Aber wenn Sie jetzt head(df_groesse) ausführen, sehen Sie dann die bereinigten Spaltennamen?
  • Sie sollten nicht, denn wenn wir ein Objekt durch eine Funktion übergeben, wird das Objekt nicht ‘aktualisiert’
    • Deshalb müssen wir das Objekt erneut mit dem Zuweisungsoperator <- zuweisen.
Code
df_groesse <- janitor::clean_names(df_groesse)

5.3 Pipes

  • Pipes werden am Ende eines Funktionsaufrufs platziert, wenn das Ergebnis dieser Funktion durch eine nachfolgende Funktion weitergegeben werden soll
    • Pipes können als “und dann…” gelesen werden
read_csv(here::here("daten", "groesse_geburtstag.csv")) |>
  head()
# A tibble: 6 × 5
  Größe Geburtsmonat L1       Haustier `Was für ein Haustier?`
  <dbl>        <dbl> <chr>    <chr>    <chr>                  
1   171            5 Englisch Lola     Hundin                 
2   168           11 Deutsch  keine    keine                  
3   182            4 Deutsch  N/A      <NA>                   
4   190            8 Deutsch  Knut     Kater                  
5   170           10 Deutsch  Emma     Hundin                 
6   163            2 Deutsch  Üzgür    Kater                  

Derzeit gibt es 2 Pipes, die in R verwendet werden können.

  1. die magrittr-Package-Pipe: %>%
  2. die neuer (seit 2023) native R-Pipe: |>
  • es gibt keine großen Unterschiede, die für unsere aktuellen Anwendungen wichtig sind
  • Sie können das Tastaturkürzel Cmd/Ctrl + Shift/Strg + M verwenden, um eine Pipe zu erzeugen
Aufgabe 3: pipes

Beispiel 3  

  1. Laden Sie den Datensatz groesse_geburtstag.csv erneut mit festen NAs und dann
    • Benutzen Sie eine Pipe, um clean_names() für den Datensatz aufzurufen, und dann
    • rufen Sie die Funktion “head()” auf
    • Überprüfen Sie die Anzahl der Beobachtungen und Variablen, gibt es ein Problem?
  2. Laden Sie den Datensatz groesse_geburtstag.csv erneut mit festen NAs, speichern Sie ihn als Objekt df_groesse, und dann
    • Verwenden Sie eine Pipe, um clean_names() auf den Datensatz anzuwenden.
  3. Warum sollte man nicht eine Pipe und die Funktion “head()” verwenden, wenn man den Datensatz als Objekt speichert?

5.4 Variablentypen

  • die wichtigsten Spaltentypen, die man kennen sollte, sind “numerisch” und “Faktor” (kategorisch)
  • Faktoren enthalten Kategorien oder Gruppen von Daten, können aber manchmal aussehen wie numerische Daten
    • Unsere Spalte “Monat” enthält zum Beispiel Zahlen, aber sie könnte auch den Namen jedes Monats enthalten
    • Es ist sinnvoll, den Mittelwert einer “numerischen” Variable zu berechnen, aber nicht den eines “Faktors”
    • Es ist zum Beispiel sinnvoll, die durchschnittliche Körpergröße zu berechnen, aber nicht den durchschnittlichen Geburtsmonat

as_factor()

  • Wir können die Funktion “as_factor()” verwenden, um einen Variablentyp in einen Faktor zu ändern.
  • Wir können entweder die R-Basissyntax verwenden, um dies zu tun, indem wir ein $ verwenden, um eine Spalte in einem Datenrahmen zu indizieren:
# mit base R
df_groesse$geburtsmonat <- as_factor(df_groesse$geburtsmonat)
  • oder wir können die Syntax tidyverse und die Funktion mutate() verwenden
# mit tidyverse
df_groesse <-
  df_groesse |> 
  mutate(geburtsmonat = as_factor(geburtsmonat))

6 Andere Dateitypen und Begrenzungszeichen

  • readr hat weitere Funktionen, die ebenfalls einfach zu benutzen sind, man muss nur wissen, wann man welche benutzt

  • read_csv2() liest Semikolon-getrennte csv-Dateien (;)

    • Dieser Dateityp ist in Ländern üblich, die , als Dezimaltrennzeichen verwenden (wie Deutschland)
  • read_tsv() liest Tabulator-getrennte Dateien

  • Die Funktion read_delim() liest Dateien mit beliebigen Trennzeichen ein.

    • sie versucht, das Trennzeichen zu erraten, es sei denn, Sie geben es mit dem Argument delim = an (z.B. read_delim(groesse_geburtstag.csv, delim = ","))

Lernziele 🏁

Heute haben wir gelernt, wie man…

  • lokale Datendateien mit dem Paket readr importiert ✅
  • fehlende Werte behandeln ✅
  • Variablen in Faktoren umwandeln ✅

Lassen Sie uns nun dieses neue Wissen anwenden.

Hausaufgaben

Anhang 6: Dateneinlesung auf der Website des Kurses.

Session Info

Hergestellt mit R version 4.4.0 (2024-04-24) (Puppy Cup) und RStudioversion 2023.12.1.402 (Ocean Storm).

sessionInfo()
R version 4.4.0 (2024-04-24)
Platform: aarch64-apple-darwin20
Running under: macOS Ventura 13.2.1

Matrix products: default
BLAS:   /Library/Frameworks/R.framework/Versions/4.4-arm64/Resources/lib/libRblas.0.dylib 
LAPACK: /Library/Frameworks/R.framework/Versions/4.4-arm64/Resources/lib/libRlapack.dylib;  LAPACK version 3.12.0

locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8

time zone: Europe/Berlin
tzcode source: internal

attached base packages:
[1] stats     graphics  grDevices datasets  utils     methods   base     

other attached packages:
 [1] magick_2.8.3    here_1.0.1      janitor_2.2.0   lubridate_1.9.3
 [5] forcats_1.0.0   stringr_1.5.1   dplyr_1.1.4     purrr_1.0.2    
 [9] readr_2.1.5     tidyr_1.3.1     tibble_3.2.1    ggplot2_3.5.1  
[13] tidyverse_2.0.0

loaded via a namespace (and not attached):
 [1] utf8_1.2.4        generics_0.1.3    renv_1.0.7        stringi_1.8.3    
 [5] hms_1.1.3         digest_0.6.35     magrittr_2.0.3    evaluate_0.23    
 [9] grid_4.4.0        timechange_0.3.0  fastmap_1.1.1     rprojroot_2.0.4  
[13] jsonlite_1.8.8    fansi_1.0.6       scales_1.3.0      cli_3.6.2        
[17] rlang_1.1.3       crayon_1.5.2      bit64_4.0.5       munsell_0.5.1    
[21] withr_3.0.0       yaml_2.3.8        tools_4.4.0       parallel_4.4.0   
[25] tzdb_0.4.0        colorspace_2.1-0  pacman_0.5.1      vctrs_0.6.5      
[29] R6_2.5.1          lifecycle_1.0.4   snakecase_0.11.1  htmlwidgets_1.6.4
[33] bit_4.0.5         vroom_1.6.5       pkgconfig_2.0.3   pillar_1.9.0     
[37] gtable_0.3.5      Rcpp_1.0.12       glue_1.7.0        xfun_0.43        
[41] tidyselect_1.2.1  rstudioapi_0.16.0 knitr_1.46        htmltools_0.5.8.1
[45] rmarkdown_2.26    compiler_4.4.0   

Literaturverzeichnis

Nordmann, E., & DeBruine, L. (2022). Applied Data Skills. Zenodo. https://doi.org/10.5281/zenodo.6365078
Wickham, H., Çetinkaya-Rundel, M., & Grolemund, G. (2023). R for Data Science (2. Aufl.).
Quellcode
---
title: "Datenimport"
subtitle: "Einlesen lokaler Datendateien"
author: "Daniela Palleschi"
institute: Humboldt-Universität zu Berlin
footer: "Woche 8 - Datenimport" 
lang: de
date: "06/04/2024"
date-format: "ddd [den] DD.MM.YYYY"
date-modified: last-modified
format: 
  html:
    output-file: datenimport_blatt.html
    include-after-body: ../../custom.html
    number-sections: true
    number-depth: 3
    toc: true
    toc-title: "heutige Themen"
    code-overflow: wrap
    code-tools: true
    self-contained: true
    include-in-header: ../../mathjax.html
  revealjs: 
    output-file: datenimport_folien.html
    include-after-body: ../../custom.html
    theme: [dark]
    width: 1600
    height: 900
    progress: true
    # smaller: true
    scrollable: true
    slide-number: c/t
    code-link: true
    code-overflow: wrap
    code-tools: true
    # logo: logos/hu_logo.png
    # css: logo.css
    incremental: true
    number-depth: 1
    toc-title: 'Überblick'
    navigation-mode: linear
    controls-layout: bottom-right
    fig-cap-location: top
    font-size: 0.6em
    slide-level: 4
    self-contained: true
    # chalkboard: true
    title-slide-attributes: 
      data-background-image: logos/logos.tif
      data-background-size: 15%
      data-background-position: 50% 92%
  pdf:
    output-file: datenimport.pdf
    toc: true
    number-sections: true
    colorlinks: true
    code-overflow: wrap
bibliography: ../../references.bib
csl: ../../apa.csl
editor_options: 
  chunk_output_type: console
---

```{r}
#| echo: false
knitr::opts_chunk$set(eval = T, # evaluate chunks
                      echo = T, # 'print code chunk?'
                      message = F, # 'print messages (e.g., warnings)?'
                      error = F, # stop when error encountered
                      warning = F) # don't print warnings
```

# Lernziele {.unnumbered .unlisted}

Heute werden wir lernen, wie man:

- lokale Datendateien (`.csv`) erstellen und speichern
- lokale Datendateien mit dem Paket `readr` importieren 
- mit fehlenden Werten umzugehen
- Variablen in Faktoren umwandeln

## Lesungen {.unnumbered}

- Kurs-Website: [Kap. 5 - Datenvisualisierung 2](https://daniela-palleschi.github.io/r4ling/mats/05-dataviz_2.html)
- [Kap. 8 (Datenimport)](https://r4ds.hadley.nz/data-import) in @wickham_r_2023
- [Kap. 4 (Datenimport)](https://psyteachr.github.io/ads-v2/04-data.html) in @nordmann_applied_2022


# Wiederholung {.unnumbered .unlisted}

Bis jetzt haben wir gelernt, wie man...

- Quarto-Skripte für die reproduzierbare Datenanalyse zu verwenden
- eingebaute Datensätze zu laden
- Daten mit `dplyr`-Verben zu verarbeiten
- Verteilungen und Beziehungen zwischen verschiedenen Variablentypen zu visualisieren

# Einrichtung

## Pakete mit `pacman`

- wir fangen an, das Paket `pacman` anstelle von `install.packages()` und `library` zu benutzen
  + die Funktion `p_load()` nimmt Paketnamen als Argumente
  + prüft dann, ob Sie das Paket installiert haben
    + wenn ja --> lädt das Paket (genau wie `library()`)
    + wenn nicht --> wird das Paket installiert und dann geladen (wie mit `install.packages()` + `library()`)
- dies erspart uns die individuelle Installation neuer Pakete

---

```{r}
#| eval: false
# install new packages IN THE CONSOLE!
install.packages("pacman")
```

```{r}
# load packages (in your script)
pacman::p_load(
               tidyverse, # wrangling
               janitor, # tidying
               here # relative file paths
               )
```

- wir haben jetzt `tidyverse` geladen und die neuen Pakete `janitor` und `here` installiert und geladen
  + Um mehr über diese Pakete herauszufinden, geben Sie `?janitor` und `?here` in der Konsole ein.

::: {.content-visible when-format="revealjs"}
## `daten`-Ordner {.uncounted .unlisted}
:::

- fügen Sie Ihrem Projektverzeichnis einen Ordner mit dem Namen `daten` hinzu (der *genau* gleich geschrieben ist).

::: callout-tip
## RProjects {.uncounted .unlisted}

- Stellen Sie sicher, dass Sie in der Klasse RProject arbeiten!
- Falls nicht, folgen Sie der Übung auf der Kurs-Website [hier](https://daniela-palleschi.github.io/r4ling/mats/07-dateneinlesung.html#rprojects)

:::


# CSV: Comma separated value

- Es gibt viele verschiedene Dateitypen, die Daten annehmen können, z. B. .xlsx, .txt, .csv, .tsv
- `.csv` ist der typischste Dateityp und steht für: Comma Separated Values

- So sieht eine einfache CSV-Datei aus, wenn man sie als Rohtext betrachtet

```{r}
#| echo: false
#| output-location: fragment
#| message: false

read_lines(here::here("daten", "students.csv")) |> cat(sep = "\n")
```

- die erste Zeile (die "Kopfzeile") enthält die Spaltennamen
- die folgenden Zeilen enthalten die Daten
- Wie viele Variablen gibt es? Wie viele Beobachtungen?

## 'Tidy' Daten

- Sie wollen, dass Ihre Daten *aufgeräumt* sind
  - aufgeräumte Daten sind rechteckig, und:
  - jede Spalte steht für eine Variable
  - jede Zeile eine Beobachtung
  - jede Zelle ein Datenpunkt (@fig-tidy-data)

::: {.content-visible when-format="html"}
```{r eval = T, fig.env = "figure", out.width="100%",  fig.pos="H", set.cap.width=T, fig.cap="Source: @wickham_r_2023 (all rights reserved)"}
#| echo: false
#| label: fig-tidy-data

library(magick)
magick::image_read(here::here("media/Wickham_tidydata.png"))
```
:::


::: {.content-visible when-format="pdf"}
```{r eval = T, fig.env = "figure", out.width="75%",  fig.pos="H", set.cap.width=T, fig.cap="Source: @wickham_r_2023 (all rights reserved)"}
#| echo: false
#| label: fig-tidy-data-1

library(magick)
magick::image_read(here::here("media/Wickham_tidydata.png"))
```
:::


## Tabelle zu csv

- Lassen Sie uns einige Spielzeugdaten in einer Tabellenkalkulation sammeln, die wir dann als CSV-Datei speichern und in R laden werden
  + Klicken Sie [hier](https://docs.google.com/spreadsheets/d/1nAKO3AGSTMmNibZLNZ4DD6okXyxxP8IDkj9PjpX0B5k/edit?usp=sharing), um zu einem bearbeitbaren Arbeitsblatt zu gelangen.
  + Geben Sie die relevanten Informationen über sich selbst ein, oder erfinden Sie einige Daten: den Namen eines Haustiers, das Sie haben/hatten, Größe, Geburtsmonat und -tag sowie Ihre erste Sprache. Wenn Sie kein Haustier haben, lassen Sie die Zelle leer.


::: {.content-visible when-format="html"}
```{r eval = T, fig.env = "figure", out.width="100%",  fig.pos="H", set.cap.width=T, fig.cap="Klicken Sie [hier](https://docs.google.com/spreadsheets/d/1nAKO3AGSTMmNibZLNZ4DD6okXyxxP8IDkj9PjpX0B5k/edit?usp=sharing) zum Hinzufügen und Herunterladen der Tabelle"}
#| echo: false
#| label: fig-spreadsheet

library(magick)
magick::image_read(here::here("media/spreadsheet_googlesheet.png"))
```
:::


::: {.content-visible when-format="pdf"}
```{r eval = T, fig.env = "figure", out.width="75%",  fig.pos="H", set.cap.width=T, fig.cap="Our spreadsheet"}
#| echo: false

library(magick)
magick::image_read(here::here("media/spreadsheet_googlesheet.png"))
```
:::

## CSV speichern

- Speichern Sie die Tabelle als `groesse_geburtstag.csv` auf Ihrem Computer, direkt in einem Ordner namens `daten` in unserem Projektverzeichnis

::: {.content-visible when-format="revealjs"}
## Aufgabe {.unlisted .unnumbered}
:::

::: callout-tip

## [Aufgabe @exm-table1]: `Saving a CSV`
::: {#exm-table1 .custom}
::: nonincremental
1. Erstellen Sie einen neuen Ordner mit dem Namen `daten` in Ihrem Projektordner (falls Sie das nicht schon getan haben).
1. Laden Sie das Google Sheet herunter und speichern Sie es in Ihrem `daten` Ordner als `groesse_geburtstag.csv`.
2. Gehen Sie zu Ihrem `daten`-Ordner und überprüfen Sie, ob die CSV-Datei dort ist.

:::
:::
:::

# Das Paket `readr`

- müssen wir nun *die Daten einlesen*
- wir müssen eine Funktion verwenden, die CSV-Daten liest, und angeben, *wo* sich die Daten in unserem RProject-Ordner befinden

- Das `readr`-Paket (Teil von `tidyverse`) kann die meisten Datentypen einlesen und hat mehrere Funktionen für verschiedene Datentypen

---

```{r}
#| echo: true
#| eval: false
#| message: false

read_csv(here::here("daten", "groesse_geburtstag.csv"))
```

```{r}
#| label: tbl-students-table
#| echo: false
#| message: false
#| tbl-cap: Data from the groesse_geburtstag.csv file as a table.

read_csv(here::here("daten", "groesse_geburtstag.csv")) |>
  knitr::kable()
```

::: {.content-visible when-format="revealjs"}
## Aufgabe {.unlisted .unnumbered}
:::

::: callout-tip

### [Aufgabe @exm-readr]: `readr`
::: {#exm-readr .custom}
::: nonincremental
1.  Importieren Sie den Datensatz "groesse_geburtstag.csv" und speichern Sie ihn als Objekt mit dem Namen `df_groesse`.
    - `df_` ist die Abkürzung für DataFrame; es ist eine gute Idee, ein Präfix vor Objektnamen zu verwenden, damit wir wissen, was jedes Objekt enthält
2.  Beim Importieren von Daten mit `read_csv` werden einige Informationen in der Konsole ausgegeben. Was wird gedruckt?
2.  Untersuche den Datensatz mit Funktionen wie `summary()` oder `head()`
3.  Sehen Sie etwas Ungewöhnliches?
:::
:::
:::

```{r}
#| eval: false
#| echo: false

df_groesse <- read_csv(here("daten", "groesse_geburtstag.csv"))
head(df_groesse) # missing data points
```

# Das Paket `here`

- Woher weiß R genau, wo der Ordner `daten` zu finden ist? 
- unser *Arbeitsverzeichnis* ist auf den Ort unseres RProjekts auf unserem Computer festgelegt
  + wann immer wir auf Daten in unserem RProjekt zugreifen wollen, sollten wir unseren Dateipfad in `here()` verschachteln
- um zu sehen, von wo aus `here()` startet, führen Sie `here()` aus

```{r}
#| output-location: fragment
here()
```

- Die Ausgabe wird auf allen Rechnern unterschiedlich aussehen, da sie relativ zu dem Ort ist, an dem wir unseren Projektordner abgelegt haben

::: {.content-visible when-format="revealjs"}
## `here` package {.unlisted .unnumbered}
:::

```{r echo = F, fig.env = "figure",out.width="70%", fig.align = "center", set.cap.width=T, fig.cap=" [Image source: Allison Horst](https://allisonhorst.com/other-r-fun) (all rights reserved)"}
knitr::include_graphics(here::here("media", "Horst_here.png"))
```



# Arbeiten mit Daten

## Fehlende Werte

- Sie haben vielleicht einige `NA` oder `N/A` Werte bemerkt
  + `N/A` wurde als Text in einer unserer Beobachtungen geschrieben, und so liest R es als solches
  + `NA` in R bezieht sich auf fehlende Daten ("Nicht verfügbar")
  + Echte fehlende Werte sind komplett leer, so dass `N/A` in unseren `df_groesse`-Daten nicht wirklich als fehlender Wert gelesen wird.
  + Um dies zu beheben, können wir das Argument `na =` für die Funktion `read_csv()` verwenden, das der Funktion `read_csv()` mitteilt, welche Werte sie mit fehlenden Werten gleichsetzen soll
  
::: {.content-visible when-format="revealjs"}
## Fehlende Werte {.unlisted .unnumbered .smaller}
:::

```{r}
#| output-location: fragment
# force "N/A" to missing values
df_groesse <- read_csv(here::here("daten", "groesse_geburtstag.csv"),
                        na = "N/A")
```

```{r}
# print the head of the data set
head(df_groesse)
```

- der Wert, der vorher `""` war, wird als `NA` gelesen
- aber was ist mit der leeren Zelle? Wir haben jetzt überschrieben, dass `read_csv()` leere Zellen als `NA` liest
  + Nun wollen wir `read_csv()` anweisen, *mehr als eine* Art von Eingabe als `NA` zu lesen, d.h. wir wollen es anweisen, `""` *und* `"N/A"` als `NA` zu lesen
  + Dazu verwenden wir unsere immer nützliche Verkettungsfunktion: `c()`
  + lassen Sie uns auch 'keine' als `NA`'s einschließen

::: {.content-visible when-format="revealjs"}
## Fehlende Werte {.unlisted .unnumbered}
:::

```{r}
#| output-location: fragment
# force "N/A", empty cells, and 'keine' to missing values
df_groesse <- read_csv(here::here("daten", "groesse_geburtstag.csv"),
                        na = c("N/A","", "keine"))
```


```{r}
# print the head of the data set
head(df_groesse)
```

## Spaltennamen

- Ein Spaltenname in unseren Daten ist von Backticks umgeben (z.B. `` `Was für ein Haustier?` ``)
  + Das liegt daran, dass er ein Leerzeichen enthält, das syntaktisch nicht gültig ist.
  + Eine schnelle Lösung ist die Funktion `clean_names()` aus dem Paket `janitor`, das wir bereits geladen haben
  
::: {.content-visible when-format="revealjs"}
## Spaltennamen {.unlisted .unnumbered}
:::

```{r}
clean_names(df_groesse)
```

- Das sieht besser aus! Aber wenn Sie jetzt `head(df_groesse)` ausführen, sehen Sie dann die bereinigten Spaltennamen?
- Sie sollten nicht, denn wenn wir ein Objekt durch eine Funktion übergeben, wird das Objekt nicht 'aktualisiert'
  + Deshalb müssen wir das Objekt erneut mit dem Zuweisungsoperator `<-` zuweisen.

```{r}
#| code-fold: true
df_groesse <- janitor::clean_names(df_groesse)
```

## Pipes

- Pipes werden am Ende eines Funktionsaufrufs platziert, wenn das Ergebnis dieser Funktion durch eine nachfolgende Funktion weitergegeben werden soll
  + Pipes können als "und dann..." gelesen werden

```{r}
read_csv(here::here("daten", "groesse_geburtstag.csv")) |>
  head()
```

::: {.content-visible when-format="revealjs"}
## Pipes {.unlisted .unnumbered}
:::

Derzeit gibt es 2 Pipes, die in R verwendet werden können. 

1. die `magrittr`-Package-Pipe: `%>%` 
2. die neuer (seit 2023) native R-Pipe: `|>` 

- es gibt keine großen Unterschiede, die für unsere aktuellen Anwendungen wichtig sind 
- Sie können das Tastaturkürzel `Cmd/Ctrl + Shift/Strg + M` verwenden, um eine Pipe zu erzeugen

::: {.content-visible when-format="revealjs"}
## Aufgabe {.unlisted .unnumbered}
:::

::: callout-tip

### [Aufgabe @exm-pipes]: pipes
::: {#exm-pipes .custom}
::: nonincremental
1.    Laden Sie den Datensatz `groesse_geburtstag.csv` erneut mit festen `NA`s *und dann*
        + Benutzen Sie eine Pipe, um `clean_names()` für den Datensatz aufzurufen, *und dann*
        + rufen Sie die Funktion "head()" auf
        + Überprüfen Sie die Anzahl der Beobachtungen und Variablen, gibt es ein Problem?
2.    Laden Sie den Datensatz `groesse_geburtstag.csv` erneut mit festen `NA`s, speichern Sie ihn als Objekt `df_groesse`, *und dann*
        + Verwenden Sie eine Pipe, um `clean_names()` auf den Datensatz anzuwenden.
4.    Warum sollte man nicht eine Pipe und die Funktion "head()" verwenden, wenn man den Datensatz als Objekt speichert?

```{r}
#| eval: false
#| echo: false
read_csv(here("daten", "groesse_geburtstag.csv"), na = c("","N/A", "keine")) |>
  clean_names() |>
  head()


df_groesse <- read_csv(here("daten", "groesse_geburtstag.csv"), na = c("","N/A", "keine")) |>
  clean_names()
```

:::
:::
:::

## Variablentypen

- die wichtigsten Spaltentypen, die man kennen sollte, sind "numerisch" und "Faktor" (kategorisch)
- Faktoren enthalten *Kategorien* oder *Gruppen* von Daten, können aber manchmal *aussehen* wie `numerische` Daten
  + Unsere Spalte "Monat" enthält zum Beispiel Zahlen, aber sie könnte auch den Namen jedes Monats enthalten
  + Es ist sinnvoll, den Mittelwert einer "numerischen" Variable zu berechnen, aber nicht den eines "Faktors"
  + Es ist zum Beispiel sinnvoll, die durchschnittliche Körpergröße zu berechnen, aber nicht den durchschnittlichen Geburtsmonat
  
### `as_factor()` {.unlisted .unnumbered}

- Wir können die Funktion "as_factor()" verwenden, um einen Variablentyp in einen Faktor zu ändern.
- Wir können entweder die R-Basissyntax verwenden, um dies zu tun, indem wir ein `$` verwenden, um eine Spalte in einem Datenrahmen zu indizieren:

```{r}
# mit base R
df_groesse$geburtsmonat <- as_factor(df_groesse$geburtsmonat)
```

- oder wir können die Syntax `tidyverse` und die Funktion `mutate()` verwenden

```{r}
# mit tidyverse
df_groesse <-
  df_groesse |> 
  mutate(geburtsmonat = as_factor(geburtsmonat))
```

# Andere Dateitypen und Begrenzungszeichen

- `readr` hat weitere Funktionen, die ebenfalls einfach zu benutzen sind, man muss nur wissen, wann man welche benutzt
  
- `read_csv2()` liest Semikolon-getrennte csv-Dateien (`;`)
  + Dieser Dateityp ist in Ländern üblich, die `,` als Dezimaltrennzeichen verwenden (wie Deutschland)

- `read_tsv()` liest Tabulator-getrennte Dateien
- Die Funktion `read_delim()` liest Dateien mit beliebigen Trennzeichen ein.
  + sie versucht, das Trennzeichen zu erraten, es sei denn, Sie geben es mit dem Argument `delim =` an (z.B. `read_delim(groesse_geburtstag.csv, delim = ",")`)



# Lernziele 🏁 {.unnumbered .unlisted}

Heute haben wir gelernt, wie man...

- lokale Datendateien mit dem Paket `readr` importiert ✅
- fehlende Werte behandeln ✅
- Variablen in Faktoren umwandeln ✅

Lassen Sie uns nun dieses neue Wissen anwenden.

# Hausaufgaben {.unnumbered}

[Anhang 6: Dateneinlesung](https://daniela-palleschi.github.io/r4ling/appendices/00-aufgaben.html#sec-app_dateneinlesung) auf der Website des Kurses.

# Session Info {.unnumbered}

```{r}
#| eval: false
#| echo: false
RStudio.Version()$version
RStudio.Version()$release_name
```


Hergestellt mit `r R.version.string` (`r R.version$nickname`) und RStudioversion 2023.12.1.402 (Ocean Storm).

```{r}
sessionInfo()
```

# Literaturverzeichnis {.unlisted .unnumbered visibility="uncounted"}

::: {#refs custom-style="Bibliography"}
:::